home *** CD-ROM | disk | FTP | other *** search
-
-
- #include "main.h"
-
-
- //------------------------------------------------------------------
- // Name: QBSP()
- // Desc: konÜtruktor
- //------------------------------------------------------------------
- QBSP::QBSP()
- {
-
- //DirectX
- g_pVB = NULL;
- Texture = NULL;
- LightMap = NULL;
-
- // Here we simply initialize our member variables to 0
- // Nastav jednoduchΘ prom∞nnΘ
- m_iNumOfVerts = 0; // PoΦet vrchol∙ scΘny nastav na 0
- m_iNumOfFaces = 0; // PoΦet ploÜek scΘny nastav na 0
- m_iNumOfTextures = 0; // PoΦet textur nastav na 0
- m_iNumOfLightmaps = 0; // PoΦet lightmap nastav na 0
- m_iNumOfNodes = 0; // PoΦet uzl∙ nastav na 0
- m_iNumOfLeafs = 0; // PoΦe list∙ nastav na 0
- m_iNumOfLeafFaces = 0; // PoΦet ploÜek v listu nastav na 0
- m_iNumOfPlanes = 0; // PoΦet d∞licφch ploch nastav na 0
- m_iVisibleFaces = 0; // Kontrolnφ prom∞nnou, kterß uklßdß, kolik ploÜek se renderuje nastav na 0
-
- // Initialize all the dynamic BSP data pointers to NULL
- m_ptBspVertex = NULL; // Vrcholy scΘny
- m_ptBspFace = NULL; // PloÜky scΘny
- m_ptBspNode = NULL; // Uzly BSP scΘny
- m_ptBspLeaf = NULL; // Listy BSP scΘny
- m_ptBspPlane = NULL; // D∞licφ plochy BSP scΘny
- m_piLeafFaces = NULL; // PloÜky list∙ BSP scΘny
- m_piLeafBrushes = NULL; //
- memset(&m_tBspVisData, 0, sizeof(TBspVisData)); // Alokuj pam∞¥ pro data detekce viditelnosti portßl∙
-
-
- }
-
-
- //------------------------------------------------------------------
- // Name: QBSP
- // Desc: deÜtruktor
- //------------------------------------------------------------------
- QBSP::~QBSP()
- {
- int i=0;
-
- /////////////
- //DirectX
- /////////////
-
- //zmaz textury
- if (Texture != NULL)
- {
- for ( i=0;i<m_iNumOfTextures;i++)
- {
- if(Texture[i] != NULL)
- {
- Texture[i]->Release();
- }
- }
- delete[] Texture ;
- }
-
- //zmaz lightmapy
- if (LightMap != NULL)
- {
- for ( i=0;i<m_iNumOfLightmaps;i++)
- {
- if(LightMap[i] != NULL)
- {
- LightMap[i]->Release();
- }
- }
- delete[] LightMap ;
- }
-
- //vertex buffer
- if (g_pVB != NULL)
- g_pVB->Release();
- g_pVB = NULL;
-
- }
-
-
- //------------------------------------------------------------------
- // Name: LoadBSP()
- // Desc: Loadni Quake 3 BSP scenu
- //------------------------------------------------------------------
- bool QBSP::LoadBSP(const char *pc_filename,float Gamma)
- {
-
- FILE *pfile = NULL; // Soubor nastav na NULL
- int i = 0; // Prom∞nnou pro cyklovßnφ nastav na 0
- char cBuf[80] ; // Premennß na chybovΘ hlaÜky
-
- //Informacie pre Log
- LogPrint("Nahravam Quake3 BSP mapu");
- sprintf(cBuf," S·bor: %s",pc_filename);
- LogPrint(cBuf);
-
- // Check if the .bsp file could be opened
- // Pokud se napoda°φ otev°φt soubor BSP, tak
- if((pfile = fopen(pc_filename, "rb")) == NULL)
- {
- // Display an error message and quit if the file can't be found.
- // Vyho∩ chybovou hlßÜku
- sprintf(" Nenasiel som s·bor %s",pc_filename);
- LogPrint(cBuf);
- return false; // Vra¥ funkci false
- }
-
- // Initialize the header and lump structures
- TBspHeader t_bsp_header = {0}; // Vyma₧ hodnoty BSP hlaviΦky
- TBspLump t_bsp_lump[LUMPS_MAX_LUMPS] = {0}; // Vyma₧ hodnoty BSP identifikaΦnφch polo₧ek
-
- // Read in the header and lump data
- // NaΦti hodnoty hlaviΦky a identifikaΦnφ polo₧ky
- fread(&t_bsp_header, 1, sizeof(TBspHeader), pfile);
- fread(&t_bsp_lump, LUMPS_MAX_LUMPS, sizeof(TBspLump), pfile);
-
- //VypφÜe informßcie pre Log
- LogPrint(" Informacie o QBSP:");
- sprintf(cBuf," verzia: %d",t_bsp_header.i_version);
- LogPrint(cBuf);
- sprintf(cBuf," pc_id: %s",t_bsp_header.pc_id );
- LogPrint(cBuf);
-
-
- // Now we know all the information about our file. We can
- // then allocate the needed memory
- //
- // Nynφ znßme vÜechny informace o souboru.
- // Dßle budeme alokovat pot°ebnou pam∞¥ pro vÜechny pot°ebnΘ prom∞nnΘ
-
- // Allocate the vertex memory
- // Alokuj pam∞¥ pro vrcholy
- m_iNumOfVerts = t_bsp_lump[LUMPS_VERTICES].i_length / sizeof(TBspVertex);
- m_ptBspVertex = new TBspVertex [m_iNumOfVerts];
-
- sprintf(cBuf," pocet vertexov: %d",m_iNumOfVerts);
- LogPrint(cBuf);
-
- // Allocate the face memory
- // Alokuj pam∞¥ pro ploÜky
- m_iNumOfFaces = t_bsp_lump[LUMPS_FACES].i_length / sizeof(TBspFace);
- m_ptBspFace = new TBspFace [m_iNumOfFaces];
-
- sprintf(cBuf," pocet facov: %d",m_iNumOfFaces);
- LogPrint(cBuf);
-
- // Allocate memory to read in the texture information.
- // Alokuj pam∞¥ pro texturovΘ informace
- m_iNumOfTextures = t_bsp_lump[LUMPS_TEXTURES].i_length / sizeof(TBspTexture);
- TBspTexture *pt_bsp_textures = new TBspTexture [m_iNumOfTextures];
-
- sprintf(cBuf," pocet textur: %d",m_iNumOfTextures);
- LogPrint(cBuf);
-
-
- // Allocate memory to read in the lightmap data.
- // Alokuj pam∞¥ pro lightmap data
- m_iNumOfLightmaps = t_bsp_lump[LUMPS_LIGHTMAPS].i_length / sizeof(TBspLightmap);
- TBspLightmap *pt_bsp_lightmaps = new TBspLightmap [m_iNumOfLightmaps ];
-
- sprintf(cBuf," pocet lightmap: %d",m_iNumOfLightmaps);
- LogPrint(cBuf);
-
- // Seek to the position in the file that stores the vertex information
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty vrchol∙
- fseek(pfile, t_bsp_lump[LUMPS_VERTICES].i_offset, SEEK_SET);
-
- // Go through all of the vertices that need to be read and swap axises
- // Projdi vÜechny vrcholy
- for(i = 0; i < m_iNumOfVerts; i++)
- {
- // Read in the current vertex
- // ╚ti ze souboru BSP hodnoty vrchol∙
- fread(&m_ptBspVertex[i], 1, sizeof(TBspVertex), pfile);
-
- // Swap the y and z values, and negate the new z so Y is up.
- // Proho∩ hodnoty Y a Z, a nastav opaΦnΘ znamΘnko u novΘ hodnoty Z
- float f_temp = m_ptBspVertex[i].pf_position[1];
- m_ptBspVertex[i].pf_position[1] = m_ptBspVertex[i].pf_position[2];
- m_ptBspVertex[i].pf_position[2] = -f_temp;
-
- }
-
- // Seek to the position in the file that stores the face information
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty ploÜek
- fseek(pfile, t_bsp_lump[LUMPS_FACES].i_offset, SEEK_SET);
-
- // Read in all the face information
- // ╚ti ze souboru BSP vÜechny hodnoty ploÜek
- fread(m_ptBspFace, m_iNumOfFaces, sizeof(TBspFace), pfile);
-
- // Seek to the position in the file that stores the texture information
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty textur
- fseek(pfile, t_bsp_lump[LUMPS_TEXTURES].i_offset, SEEK_SET);
-
- // Read in all the texture information
- // ╚ti ze souboru BSP vÜechny hodnoty textur
- fread(pt_bsp_textures, m_iNumOfTextures, sizeof(TBspTexture), pfile);
-
- //Alokuj pama¥ pre textury
- Texture = new LPDIRECT3DTEXTURE9[m_iNumOfTextures];
-
- // Go through all of the textures
- // Projdi vÜechny textury
- for(i = 0; i < m_iNumOfTextures; i++)
- {
- // Create a texture from the image
- // NaΦti texturu
-
- char TexFN1[80];
- char TexFN2[80];
- sprintf(TexFN1,"%s.jpg",pt_bsp_textures[i].pc_filename);
- sprintf(TexFN2,"%s.tga",pt_bsp_textures[i].pc_filename);
-
- sprintf(cBuf," nahravam texturu: %d %s",i,TexFN1);
- LogPrint(cBuf);
-
- Texture[i] = NULL;
-
- if (FAILED(D3DXCreateTextureFromFileEx(g_pd3dDevice, //Our D3D Device
- TexFN1, //Filename of our texture
- D3DX_DEFAULT, //Width:D3DX_DEFAULT = Take from file
- D3DX_DEFAULT, //Height:D3DX_DEFAULT = Take from file
- Engine.MipMapLevels, //MipLevels
- 0, //Usage, Is this to be used as a Render Target? 0 == No
- Engine.TextureFormat, //32-bit with Alpha, everything should support this
- D3DPOOL_MANAGED,//Pool, let D3D Manage our memory
- D3DX_DEFAULT, //Filter:Default filtering
- D3DX_DEFAULT, //MipFilter, used for filtering mipmaps
- 0, //Disable ColourKey
- NULL, //SourceInfo, returns extra info if we want it (we don't)
- NULL, //Palette:We're not using one
- &Texture[i])))
- {
- sprintf(cBuf," nahravam texturu: %d %s",i,TexFN2);
- LogPrint(cBuf);
- if (FAILED(D3DXCreateTextureFromFileEx(g_pd3dDevice, //Our D3D Device
- TexFN2, //Filename of our texture
- D3DX_DEFAULT, //Width:D3DX_DEFAULT = Take from file
- D3DX_DEFAULT, //Height:D3DX_DEFAULT = Take from file
- Engine.MipMapLevels, //MipLevels
- 0, //Usage, Is this to be used as a Render Target? 0 == No
- D3DFMT_UNKNOWN, //32-bit with Alpha, everything should support this
- D3DPOOL_MANAGED,//Pool, let D3D Manage our memory
- D3DX_DEFAULT, //Filter:Default filtering
- D3DX_DEFAULT, //MipFilter, used for filtering mipmaps
- 0, //Disable ColourKey
- NULL, //SourceInfo, returns extra info if we want it (we don't)
- NULL, //Palette:We're not using one
- &Texture[i])))
- {
- LogPrint(" chyba");
- }
- else
- {
- LogPrint(" OK");
- }
- }
- else
- {
- LogPrint(" OK");
- }
-
- }
-
- // We can now free all the texture information since we already loaded them
- // Vyma₧ vÜechny texturovΘ hodnoty z pam∞ti
- delete [] pt_bsp_textures;
-
- // Seek to the position in the file that stores the lightmap information
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty lightmap
- fseek(pfile, t_bsp_lump[LUMPS_LIGHTMAPS].i_offset, SEEK_SET);
-
- //inicializuj lightmapy
- LightMap = new LPDIRECT3DTEXTURE9[m_iNumOfLightmaps];
-
- // Go through all of the lightmaps and read them in
- // Projdi vÜechny lightmapy
- for(i = 0; i < m_iNumOfLightmaps; i++)
- {
- // Read in the RGB data for each lightmap
- // NaΦti RGB data vÜech lightmap
- fread(&pt_bsp_lightmaps[i], 1, sizeof(TBspLightmap), pfile);
-
- // Create a texture map for each lightmap that is read in. The lightmaps
- // are always 128 by 128.
- // Vytvo° lightmap texturu kterß mß velikost v₧dy 128x128
-
- sprintf(cBuf," Vytvaram LightMapu ID: %d",i);
- LogPrint(cBuf);
-
- LightMap[i] = NULL;
-
- if (FAILED(D3DXCreateTexture(g_pd3dDevice,128,128,0,0,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,&LightMap[i])))
- {
- LogPrint(" chyba");
- }
- else
- {
- LogPrint(" OK");
- }
-
- //skopiruj do lightmapy
- D3DSURFACE_DESC pDesc;
- D3DLOCKED_RECT d3dlr;
- LightMap[i]->GetLevelDesc(0, &pDesc );
-
- LogPrint(" Otvaram lightmapu");
- LightMap[i]->LockRect( 0, &d3dlr, 0, 0 );
- DWORD *pDst = (DWORD *)d3dlr.pBits;
-
- for (int x=0;x<128;x++)
- {
- for (int y=0;y<128;y++)
- {
- //gamma
- float f_scale = 1.0f; // M∞°φtko nastav na 1
- float f_temp = 0.0f; // Odkßdacφ zßsobnφk nastav na 0
- float f_r = 0, f_g = 0, f_b = 0; // BarevnΘ kanßly nastav na 0
-
- f_r = (float) pt_bsp_lightmaps[i].pppby_image_bits[y][x][0];
- f_g = (float) pt_bsp_lightmaps[i].pppby_image_bits[y][x][1];
- f_b = (float) pt_bsp_lightmaps[i].pppby_image_bits[y][x][2];
-
- f_r = f_r * Gamma / 255.0f;
- f_g = f_g * Gamma / 255.0f;
- f_b = f_b * Gamma / 255.0f;
-
- if(f_r > 1.0f && (f_temp = (1.0f / f_r)) < f_scale) f_scale = f_temp;
- if(f_g > 1.0f && (f_temp = (1.0f / f_g)) < f_scale) f_scale = f_temp;
- if(f_b > 1.0f && (f_temp = (1.0f / f_b)) < f_scale) f_scale = f_temp;
-
- f_scale *= 255.0f;
- f_r *= f_scale;
- f_g *= f_scale;
- f_b *= f_scale;
-
- pt_bsp_lightmaps[i].pppby_image_bits[y][x][0] = (BYTE) f_r;
- pt_bsp_lightmaps[i].pppby_image_bits[y][x][1] = (BYTE) f_g;
- pt_bsp_lightmaps[i].pppby_image_bits[y][x][2] = (BYTE) f_b;
-
- pDst[y*128+x] = (255 << 24 | pt_bsp_lightmaps[i].pppby_image_bits[y][x][0] << 16 |
- pt_bsp_lightmaps[i].pppby_image_bits[y][x][1] << 8 |
- pt_bsp_lightmaps[i].pppby_image_bits[y][x][2] );
- }
- }
-
- LogPrint(" Zatvaram lightmapu");
- LightMap[i]->UnlockRect (0);
- }
-
-
- // Delete the image bits because we are already done with them
- // Vyma₧ vÜechny lightmap hodnoty z pam∞ti
- delete [] pt_bsp_lightmaps;
-
- // Store the number of nodes and allocate the memory to hold them
- // NaΦti poΦet uzl∙ a alokuj pro n∞ pam∞¥
- m_iNumOfNodes = t_bsp_lump[LUMPS_NODES].i_length / sizeof(TBspNode);
- m_ptBspNode = new TBspNode [m_iNumOfNodes];
-
- // Seek to the position in the file that hold the nodes and store them in m_ptBspNode
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty uzl∙ a tyto hodnoty naΦti
- fseek(pfile, t_bsp_lump[LUMPS_NODES].i_offset, SEEK_SET);
- fread(m_ptBspNode, m_iNumOfNodes, sizeof(TBspNode), pfile);
-
- // Store the number of leafs and allocate the memory to hold them
- // NaΦti poΦet list∙ a alokuj pro n∞ pam∞¥
- m_iNumOfLeafs = t_bsp_lump[LUMPS_LEAFS].i_length / sizeof(TBspLeaf);
- m_ptBspLeaf = new TBspLeaf [m_iNumOfLeafs];
-
- // Seek to the position in the file that holds the leafs and store them in m_ptBspLeaf
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty list∙ a tyto hodnoty naΦti
- fseek(pfile, t_bsp_lump[LUMPS_LEAFS].i_offset, SEEK_SET);
- fread(m_ptBspLeaf, m_iNumOfLeafs, sizeof(TBspLeaf), pfile);
-
- // Now we need to go through and convert all the leaf bounding boxes
- // to the normal OpenGL Y up axis.
- // Projdi vÜechny listy a proho∩ hodnoty Y na Z vÜech obßlek list∙.
- // OpenGL mß toti₧ Y a Z hodnoty prohozeny oproti
- // ostatnφm grafick²m program∙m (nap°. 3dsMax)
- for(i = 0; i < m_iNumOfLeafs; i++)
- {
- // Swap the min y and z values, then negate the new Z
- // Proho∩ minimßlnφ hodnoty obßlky Y na Z.
- // U Z hodnoty nastav opaΦnΘ znamΘnko
- float f_temp = (float) m_ptBspLeaf[i].pi_min_box[1];
- m_ptBspLeaf[i].pi_min_box[1] = (int) m_ptBspLeaf[i].pi_min_box[2];
- m_ptBspLeaf[i].pi_min_box[2] = (int)-f_temp;
-
- // Swap the max y and z values, then negate the new Z
- // Proho∩ maximßlnφ hodnoty obßlky Y na Z.
- // U Z hodnoty nastav opaΦnΘ znamΘnko
- f_temp = (float) m_ptBspLeaf[i].pi_max_box[1];
- m_ptBspLeaf[i].pi_max_box[1] = (int)m_ptBspLeaf[i].pi_max_box[2];
- m_ptBspLeaf[i].pi_max_box[2] = (int)-f_temp;
-
- }
-
- // Store the number of leaf faces and allocate the memory for them
- // NaΦti poΦet ploÜek list∙ a alokuj pro n∞ pam∞¥
- m_iNumOfLeafFaces = t_bsp_lump[LUMPS_LEAF_FACES].i_length / sizeof(int);
- m_piLeafFaces = new int [m_iNumOfLeafFaces];
-
- // Seek to the leaf faces lump, then read it's data
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty ploÜky lis∙ a tyto hodnoty naΦti
- fseek(pfile, t_bsp_lump[LUMPS_LEAF_FACES].i_offset, SEEK_SET);
- fread(m_piLeafFaces, m_iNumOfLeafFaces, sizeof(int), pfile);
-
- // Store the number of planes, then allocate memory to hold them
- // NaΦti poΦet d∞licφch ploch a alokuj pro n∞ pam∞¥
- m_iNumOfPlanes = t_bsp_lump[LUMPS_PLANES].i_length / sizeof(TBspPlane);
- m_ptBspPlane = new TBspPlane [m_iNumOfPlanes];
-
- // Seek to the planes lump in the file, then read them into m_ptBspPlane
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty d∞licφch ploch a tyto hodnoty naΦti
- fseek(pfile, t_bsp_lump[LUMPS_PLANES].i_offset, SEEK_SET);
- fread(m_ptBspPlane, m_iNumOfPlanes, sizeof(TBspPlane), pfile);
-
- // Go through every plane and convert it's normal to the Y-axis being up
- // Projdi vÜechny d∞licφ plochy a proho∩ hodnoty Y na Z vÜech obßlek list∙.
- // U Z hodnoty proho∩ znamΘnko
- for(i = 0; i < m_iNumOfPlanes; i++)
- {
- float f_temp = m_ptBspPlane[i].pf_normal[1];
- m_ptBspPlane[i].pf_normal[1] = m_ptBspPlane[i].pf_normal[2];
- m_ptBspPlane[i].pf_normal[2] = -f_temp;
- }
-
- // Seek to the position in the file that holds the visibility lump
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty bitov²ch informacφ viditelnosti a tyto hodnoty naΦti
- fseek(pfile, t_bsp_lump[LUMPS_VIS_DATA].i_offset, SEEK_SET);
-
- // Check if there is any visibility information first
- // Pokud existuje n∞jakß bitovß informace viditelnosti
- if(t_bsp_lump[LUMPS_VIS_DATA].i_length)
- {
- // Read in the number of vectors and each vector's size
- // NaΦti poΦet klastr∙ a jejich bytovou(1byte = 8bit∙) velikosti
- fread(&(m_tBspVisData.i_num_of_clusters), 1, sizeof(int), pfile);
- fread(&(m_tBspVisData.i_bytes_per_cluster), 1, sizeof(int), pfile);
-
- // Allocate the memory for the cluster bitsets
- // Alokuj pam∞¥ pro bitovΘ hodnoty klastr∙
- int i_size = m_tBspVisData.i_num_of_clusters * m_tBspVisData.i_bytes_per_cluster;
- m_tBspVisData.pby_cluster_bitsets = new byte [i_size];
-
- // Read in the all the visibility bitsets for each cluster
- // NaΦti vÜechny bitovΘ hodnoty klastr∙ pro detekci viditelnosti
- fread(m_tBspVisData.pby_cluster_bitsets, 1, sizeof(byte) * i_size, pfile);
- }
- // Otherwise, we don't have any visibility data (prevents a crash)
- else // Pokud neexistujφ ₧ßdnΘ bitovΘ informace viditelnosti, tak
- m_tBspVisData.pby_cluster_bitsets = NULL; // Nastav bitovΘ hodnoty klastr∙ na NULL
-
-
-
- // NaΦti poΦet koliznφch srß₧ek v listu a alokuj pro n∞ pam∞¥
- m_iNumOfLeafBrushes = t_bsp_lump[LUMPS_LEAF_BRUSHES].i_length / sizeof(int);
- m_piLeafBrushes = new int[m_iNumOfLeafBrushes];
-
-
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty koliznφch srß₧ek v listu
- fseek(pfile, t_bsp_lump[LUMPS_LEAF_BRUSHES].i_offset, SEEK_SET);
- fread(m_piLeafBrushes, m_iNumOfLeafBrushes, sizeof(int), pfile);
-
-
- // NaΦti poΦet koliznφch srß₧ek a alokuj pro n∞ pam∞¥
- m_iNumOfBrushes = t_bsp_lump[LUMPS_BRUSHES].i_length / sizeof(TBspBrush);
- m_ptBspBrush = new TBspBrush[m_iNumOfBrushes];
-
- sprintf(cBuf," Kolizne zrazky: %d",m_iNumOfLeafBrushes);
- LogPrint(cBuf);
-
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty koliznφch srß₧ek
- fseek(pfile, t_bsp_lump[LUMPS_BRUSHES].i_offset, SEEK_SET);
- fread(m_ptBspBrush, m_iNumOfBrushes, sizeof(TBspBrush), pfile);
-
- // NaΦti poΦet koliznφch stran srß₧ek a alokuj pro n∞ pam∞¥
- m_iNumOfBrushSides = t_bsp_lump[LUMPS_BRUSH_SIDES].i_length / sizeof(TBspBrushSides);
- m_ptBspBrushSides = new TBspBrushSides[m_iNumOfBrushSides];
-
- sprintf(cBuf," Kolizne strany: %d",m_iNumOfBrushSides);
- LogPrint(cBuf);
-
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty koliznφch stran srß₧ek
- fseek(pfile, t_bsp_lump[LUMPS_BRUSH_SIDES].i_offset, SEEK_SET);
- fread(m_ptBspBrushSides, m_iNumOfBrushSides, sizeof(TBspBrushSides), pfile);
-
- // NaΦti poΦet efekt∙ a alokuj pro n∞ pam∞¥
- m_iNumOfShaders = t_bsp_lump[LUMPS_SHADERS].i_length / sizeof(TBspShader);
- m_ptBspShader = new TBspShader[m_iNumOfShaders];
-
- sprintf(cBuf," Pocet efektov: %d",m_iNumOfShaders);
- LogPrint(cBuf);
-
-
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty koliznφch stran srß₧ek
- fseek(pfile, t_bsp_lump[LUMPS_SHADERS].i_offset, SEEK_SET);
- fread(m_ptBspShader, m_iNumOfShaders, sizeof(TBspShader), pfile);
-
- // NaΦti indexy braÜφ efekt∙.
- // Index nßm bude slou₧it pro zamezenφ kolize
- // kamery s efektem. Kolize nap°. s mlhou je nesmysl, ₧e.
- m_piShaderBrushIndex = new int[m_iNumOfShaders]; // Alokuj pot°ebnou pam∞¥ pro index
- for(i=0; i<m_iNumOfShaders; i++)
- {
- m_piShaderBrushIndex[i] = m_ptBspShader[i].i_brush_index; // NaΦti index
- }
-
- // NaΦti poΦet model∙ a alokuj pro n∞ pam∞¥
- m_iNumOfModels = t_bsp_lump[LUMPS_MODELS].i_length / sizeof(TBspModel);
- m_ptBspModel = new TBspModel[m_iNumOfModels];
-
- sprintf(cBuf," Pocet modelov: %d",m_iNumOfModels);
- LogPrint(cBuf);
-
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty koliznφch stran srß₧ek
- fseek(pfile, t_bsp_lump[LUMPS_MODELS].i_offset, SEEK_SET);
- fread(m_ptBspModel, m_iNumOfModels, sizeof(TBspModel), pfile);
-
- // NaΦti indexy braÜφ efekt∙.
- // Index nßm bude slou₧it pro zamezenφ kolize
- // kamery s modelem
- m_piModelBrushIndex = new int[m_iNumOfModels]; // Alokuj pot°ebnou pam∞¥ pro index
- for(i=0; i<m_iNumOfModels; i++)
- {
- m_piModelBrushIndex[i] = m_ptBspModel[i].i_brush_index; // NaΦti index
- }
-
- // Store the number of mesh vertices and allocate the memory for them
- // NaΦti poΦet vrchol∙ meÜφ a alokuj pro n∞ pam∞¥
- m_iNumOfMeshVertices = t_bsp_lump[LUMPS_MESH_VERTS].i_length / sizeof(int);
- m_piMeshVertices = new int [m_iNumOfMeshVertices];
-
- sprintf(cBuf," Pocet mesh vertex: %d",m_iNumOfMeshVertices);
- LogPrint(cBuf);
-
- // Seek to the mesh vertices lump, then read it's data
- // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
- // ulo₧enΘ hodnoty vrchol∙ meÜφ a tyto hodnoty naΦti
- fseek(pfile, t_bsp_lump[LUMPS_MESH_VERTS].i_offset, SEEK_SET);
- fread(m_piMeshVertices, m_iNumOfMeshVertices, sizeof(int), pfile);
-
- // Close the file
- // Zav°i soubor
- fclose(pfile);
-
- //Fill Vertex Buffer
- //Napln Vertex Buffer
- FillVertexBuffer();
-
- // Here we allocate enough bits to store all the faces for our bitset
- // Alokuj dostateΦnΘ mno₧stvφ bit∙ pro vÜechny ploÜky, bitovΘ nastavenφ klastr∙
- m_BitsetFacesDrawn.Resize(m_iNumOfFaces);
-
- // Return a success
- // Pokud jsi doÜel a₧ sem, tak vra¥ funkci true
- return true;
-
- }
-
-
- //------------------------------------------------------------------
- // Name: RenderFace()
- // Desc: Render jedneho Facu
- //------------------------------------------------------------------
- void QBSP::RenderFace(int i_face_index)
- {
-
-
- TBspFace *p_bsp_face = &m_ptBspFace[i_face_index];
-
- g_pd3dDevice->SetTexture( 0, Texture[p_bsp_face->i_texture_id] );
-
- //ak je pouzita lightmapa
- if(p_bsp_face->i_lightmap_id >= 0)
- g_pd3dDevice->SetTexture( 1, LightMap[p_bsp_face->i_lightmap_id] );
-
-
- //nastav texture stage pre LightMapping
- g_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
- g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
-
- g_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX,1);
- g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE );
- g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
-
- //ak je stena
- if(p_bsp_face->i_type == 1)
- {
-
- g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEXQBSP));
- g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEXQBSP);
- g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, p_bsp_face->i_start_vert_index
- , p_bsp_face->i_num_of_verts-2);
- }
-
- g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
-
- if(p_bsp_face->i_type == 3)
- {
- //vytvori pole vertexov
- CUSTOMVERTEXQBSP *MeshVertex = NULL;
- MeshVertex = new CUSTOMVERTEXQBSP[p_bsp_face->i_num_mesh_verts];
-
- for(int i=0; i<p_bsp_face->i_num_mesh_verts; i++) // Proje∩ vÜechny vrcholy meÜφ
- {
- // Zφskej index aktußlnφho vrcholu
- int i_vert_index = m_piMeshVertices[p_bsp_face->i_mesh_vert_index + i];
-
- // Nastav texturovΘ koordinace
- MeshVertex[i].pos.x = m_ptBspVertex[p_bsp_face->i_start_vert_index + i_vert_index].pf_position[0];
- MeshVertex[i].pos.y = m_ptBspVertex[p_bsp_face->i_start_vert_index + i_vert_index].pf_position[1];
- MeshVertex[i].pos.z = m_ptBspVertex[p_bsp_face->i_start_vert_index + i_vert_index].pf_position[2];
-
- MeshVertex[i].color = 0xffffffff;
-
- MeshVertex[i].tu = m_ptBspVertex[p_bsp_face->i_start_vert_index + i_vert_index].pf_texture_coord[0];
- MeshVertex[i].tv = m_ptBspVertex[p_bsp_face->i_start_vert_index + i_vert_index].pf_texture_coord[1];
-
- }
-
-
- //Vykresli Pole
- g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEXQBSP );
- g_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST,p_bsp_face->i_num_mesh_verts/3,(BYTE**)&MeshVertex[0], sizeof(CUSTOMVERTEXQBSP));
-
- if (MeshVertex != NULL)
- delete MeshVertex;
-
- }
-
-
-
- }
-
- //------------------------------------------------------------------
- // Name:
- // Desc:
- //------------------------------------------------------------------
- void QBSP::RenderBSP()
- {
-
- //vypni svetla
- g_pd3dDevice->SetRenderState( D3DRS_LIGHTING,false );
-
-
- // Reset our bitset so all the slots are zero.
- // VyΦisti pam∞¥ ve kterΘ jsou ulo₧ena bitovß data vykreslen²ch ploÜek
- m_BitsetFacesDrawn.ClearAll();
-
- // Grab the leaf index that our camera is in
- // Zφskej index listu, ve kterΘm se nachßzφ kamera
- int i_leaf_index = FindLeaf(Camera.Pos);
-
- // Grab the cluster that is assigned to the leaf
- // Zφskej podle indexu klastr listu, ve kterΘm se nachßzφ kamera
- int i_camera_in_cluster = m_ptBspLeaf[i_leaf_index].i_cluster;
-
- // Initialize our counter variables (start at the last leaf and work down)
- int i = m_iNumOfLeafs; // PoΦet list∙ p°edej hodnot∞ i
- m_iVisibleFaces = 0; // Vyma₧ vyditelnΘ ploÜky
-
- // Since we are using frustum culling to only draw the visible BSP leafs,
- // we need to calculate the frustum every frame. This needs to happen
- // right after we position our camera. Now the frustum planes can be defined.
- // Zφskej hodnoty zornΘho pole kamery z projekΦnφ a modelovΘ matice scΘny.
- // Podle hodnot zornΘho pole pak budeme urΦovat, kterΘ BSP listy jsou viditelnΘ
- // a kterΘ ne. Tento v²poΦet musφme provßd∞t v ka₧dΘm cyklu p°ekreslovßnφ scΘny.
- //m_Frustum.CalculateFrustum();
-
-
- // Go through all the leafs and check their visibility
- // Projdφ vÜechny listy a zjisti jejich viditelnost
- while(i--)
- {
- // Get the current leaf that is to be tested for visibility from our camera's leaf
- // Zφskej aktußlnφ list, kter² budeme pou₧φvat k detekci viditelnosti
- TBspLeaf *p_bsp_leaf = &(m_ptBspLeaf[i]);
-
- //
- //PVS
- //
- // If the current leaf can't be seen from our cluster, go to the next leaf
- // Jestli₧e aktußlnφ klastr listu neni viditeln² z klastru, ve kterΘm je kamera, tak
- if(!IsClusterVisible(i_camera_in_cluster, p_bsp_leaf->i_cluster))
- continue; // Se vra¥ na zaΦßtek cyklu na dalÜφ list
-
- //
- //FRUSTRUM CULLING
- //
- // If the current leaf is not in the camera's frustum, go to the next leaf
- // Jestli₧e aktußlnφ list nenφ v zornΘm ·hlu kamery, tak
- if(!Camera.FrustrumBox(Get3D((float)p_bsp_leaf->pi_min_box[0], (float)p_bsp_leaf->pi_min_box[1], (float)p_bsp_leaf->pi_min_box[2]),
- Get3D((float)p_bsp_leaf->pi_max_box[0], (float)p_bsp_leaf->pi_max_box[1], (float)p_bsp_leaf->pi_max_box[2])))
- continue; // Se vra¥ na zaΦßtek cyklu na dalÜφ list
-
- // If we get here, the leaf we are testing must be visible in our camera's view.
- // Get the number of faces that this leaf is in charge of.
- // Zφskej poΦet ploÜek v listu
- int i_num_of_leaf_faces = p_bsp_leaf->i_num_of_leaf_faces;
-
- // Loop through and render all of the faces in this leaf
- // Projdi vÜechny ploÜky listu
- while(i_num_of_leaf_faces--)
- {
- // Grab the current face index from our leaf faces array
- // Zφskej index ploÜky
- int i_face_index = m_piLeafFaces[p_bsp_leaf->i_leaf_face + i_num_of_leaf_faces];
-
-
- // Since many faces are duplicated in other leafs, we need to
- // make sure this face already hasn't been drawn.
- // Jestli₧e ploÜka, kterß mß b²t vykreslena, nebyla ji₧ vykreslena, tak
- if(!m_BitsetFacesDrawn.On(i_face_index))
- {
- // Increase the rendered face count to display for fun
- // P°idej 1 k poΦtu viditeln²ch ploÜek
- m_iVisibleFaces++;
-
- // Set this face as drawn and render it
- // Nastav, ploÜku jako vykreslenou
- m_BitsetFacesDrawn.Set(i_face_index);
-
- // Vykresli ploÜku podle hodnoty indexu
- RenderFace(i_face_index);
- }
- }
- }
-
- }
-
-
- //------------------------------------------------------------------
- // Name: FillVertexBuffer
- // Desc: vytvori a nalpni vertex buffer
- //------------------------------------------------------------------
- void QBSP::FillVertexBuffer()
- {
-
- LogPrint(" Vytvaram Vertex Buffer");
-
- //vytvaranie vertex buffera
- if (FAILED(g_pd3dDevice->CreateVertexBuffer(m_iNumOfVerts*sizeof(CUSTOMVERTEXQBSP),
- D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEXQBSP,
- D3DPOOL_DEFAULT, &g_pVB, NULL )))
- {
- LogPrint(" chyba");
- }
- else
- {
- LogPrint(" OK");
- }
-
-
- //naplnanie VB
-
- //Vertex do ktoreho sa uklada
- CUSTOMVERTEXQBSP *Vertex;
-
- //Otvor VB
- LogPrint(" Otvaram Vertex Buffer");
- g_pVB->Lock(0, 0, (void**)&Vertex, 0 ) ;
-
- //zobrazi model do pola vertexov
- for (int i = 0;i<m_iNumOfVerts;i++)
- {
-
- Vertex[i].pos.x = m_ptBspVertex[i].pf_position[0];
- Vertex[i].pos.y = m_ptBspVertex[i].pf_position[1];
- Vertex[i].pos.z = m_ptBspVertex[i].pf_position[2];
-
- Vertex[i].tu = m_ptBspVertex[i].pf_texture_coord[0];
- Vertex[i].tv = m_ptBspVertex[i].pf_texture_coord[1];
-
- Vertex[i].tu2 = m_ptBspVertex[i].pf_lightmap_coord[0];
- Vertex[i].tv2 = m_ptBspVertex[i].pf_lightmap_coord[1];
-
- Vertex[i].color = D3DXCOLOR(255,255,255,255);
-
-
- }
-
- //zatvorVB
- LogPrint(" Zatvaram Vertex Buffer");
- g_pVB->Unlock();
-
- }
-
- //------------------------------------------------------------------
- // Name: FindLeaf()
- // Desc: Vrßti ID listu v ktorom sa nachßdza kamera
- //------------------------------------------------------------------
- int QBSP::FindLeaf(VECTOR3D CamPos)
- {
-
- int i = 0; // Nßvratovß hodnota indexu listu
- float f_distance = 0.0f; // Vzdßlenost od plochy, kdy dochßzφ k detekci
-
- // Continue looping until we find a negative index
- // Cykluj, dokud nebude nßvratovß hodnota indexu listu zßpornß
- while(i >= 0)
- {
- // Get the current node, then find the slitter plane from that
- // node's plane index. Notice that we use a constant reference
- // to store the plane and node so we get some optimization.
- // Zφskej aktußlnφ uzek a d∞licφ plochu s indexem tohoto uzlu.
- const TBspNode& node = m_ptBspNode[i]; // Zφskej uzel
- const TBspPlane& plane = m_ptBspPlane[node.i_plane]; // Zφskej d∞licφ plochu tohoto uzlu
-
- // Use the Plane Equation (Ax + By + Cz + D = 0) to find if the
- // camera is in front of or behind the current splitter plane.
- // Pou₧ij obecnou rovnici roviny (Ax + By + Cz + D = 0) pro v²poΦet,
- // zda je kamera p°ed, nebo za d∞licφ plochou.
- f_distance = plane.pf_normal[0] * CamPos.X +
- plane.pf_normal[1] * CamPos.Y +
- plane.pf_normal[2] * CamPos.Z - plane.f_distance;
-
- // If the camera is in front of the plane
- // Pokud je v²sledek rovnice v∞tÜφ nebo rovno 0,
- // tak je kamera p°ed d∞licφ rovinou, je tedy v p°ednφm listu
- if(f_distance >= 0)
- {
- // Assign the current node to the node in front of itself
- // Ulo₧ p°ednφ hodnotu uzlu do indexu listu
- i = node.i_front;
- }
- // Else if the camera is behind the plane
- // Pokud je v²sledek rovnice menÜφ ne₧ 0,
- // tak je kamera za d∞licφ rovinou, je tedy v zadnφm listu
- else
- {
- // Assign the current node to the node behind itself
- // Ulo₧ zadnφ hodnotu uzlu do indexu listu
- i = node.i_back;
- }
- }
-
-
- return ~i; //vrßti i
-
- }
-
- //------------------------------------------------------------------
- // Name: IsClusterVisible()
- // Desc: Zisti ci je Cluster viditelny z daneho clustra
- //------------------------------------------------------------------
- int QBSP::IsClusterVisible(int i_camera_in_cluster, int i_test_cluster)
- {
-
- // Make sure we have valid memory and that the current cluster is > 0.
- // If we don't have any memory or a negative cluster, return a visibility (1).
- // Ujisti se jestli jsou klastrovß data v pam∞¥i a ₧e klastr ve kterΘm je kamera je > 0
- // Jestli₧e neexistujφ klastrovß data, nebo klastr ve kterΘm je kamera je < 0,
- // tak vra¥ funkci 1. Tφm tento klastr oznaΦφme jako viditeln².
- // Pokud by se oznaΦil jako neviditeln², mohlo by se stßt, ₧e by
- // ve scΘn∞ mohly vzniknout dφry.
- if(!m_tBspVisData.pby_cluster_bitsets || i_camera_in_cluster < 0) return 1;
-
- // Use binary math to get the 8 bit visibility set for the current cluster
- // Pou₧ij binßrnφ operaci pro zφskßnφ 8 bitovΘ informace o viditelnosti klastru ve kterΘm je kamera
- // Bitovß operace (test >> 3) posune bity v "test" o 3 pozice doprava,
- // Φφm₧ provede to samΘ (avÜak rychleji), jako (test / 8)
- byte by_vis_set = m_tBspVisData.pby_cluster_bitsets[(i_camera_in_cluster * m_tBspVisData.i_bytes_per_cluster) + (i_test_cluster >> 3)];
-
- // Now that we have our vector (bitset), do some bit shifting to find if
- // the "test" cluster is visible from the "current" cluster, according to the bitset.
- // Porovnej pomocφ bitovΘho souΦinu "&" bitovΘ hodnoty klastru ve kterΘm je kamera a testovanΘho klastru.
- // Bitov² souΦin "&" nßm vracφ 1, pokud jsou ob∞ hodnoty stejnΘ, a 0 pokud jsou rozdφlnΘ
- // Bitov² posun doleva "1 <<" vynßsobφ jedniΦkou v²slednou hodnotu bitovΘho souΦinu ((test) & 7))
- // Pokud bude hodnota nap°. 1, vynßsobφ se (1 * 2), pokud bude hodnota nap°. 4, vynßsobφ (1 * 16) atd..
- int result = by_vis_set & (1 << ((i_test_cluster) & 7));
-
- // Return the result ( either 1 (visible) or 0 (not visible) )
- // Vra¥ funkci v²sledek bitov²ch operacφ (v²sledek 1 = viditeln² klastr, v²sledek 0 = neviditeln² klastr)
- return ( result );
-
-
- }
-
- //------------------------------------------------------------------
- // Name: CheckBrushCollision()
- // Desc: Zisti koliziu s listom
- //------------------------------------------------------------------
- bool QBSP::CheckBrushCollision(int i_leaf_index)
- {
-
-
- TBspLeaf *pt_bsp_leaf = &(m_ptBspLeaf[i_leaf_index]); // Zφskej hodnoty aktußlnφho listu
- int i_num_leaf_brushes = pt_bsp_leaf->i_num_of_leaf_brushes; // Zφskej poΦet kolizφ
-
- // Jestli₧e list obsahuje kolize
- if(i_num_leaf_brushes)
- {
- return true;
- }
- else // Pokud nedochßzφ k detekci kolize
- {
- return false;
- }
-
- }
-
- //------------------------------------------------------------------
- // Name: ColliseBSP()
- // Desc: Zisti koliziu
- //------------------------------------------------------------------
- bool QBSP::ColliseBSP(VECTOR3D Point)
- {
-
- int i_ray_leaf_index = FindLeaf(Point);
-
- if(CheckBrushCollision(i_ray_leaf_index))
- {
- return true;
- }
- else
- {
- return false;
- }
-
-
- }